home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / Spinner.java < prev    next >
Text File  |  1998-06-30  |  12KB  |  432 lines

  1. /*
  2.  * @(#)Spinner.java    1.19 02/16/98
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20.  
  21. package com.sun.java.swing.plaf.basic;
  22.  
  23. import java.awt.*;
  24. import java.awt.event.*;
  25. import java.io.*;
  26. import com.sun.java.swing.*;
  27. import com.sun.java.swing.border.*;
  28. import com.sun.java.swing.plaf.*;
  29.  
  30.  
  31. /**
  32.  * A typein field for an integer.
  33.  * <p>
  34.  * Warning: serialized objects of this class will not be compatible with
  35.  * future swing releases.  The current serialization support is appropriate
  36.  * for short term storage or RMI between Swing1.0 applications.  It will
  37.  * not be possible to load serialized Swing1.0 objects with future releases
  38.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  39.  * baseline for the serialized form of Swing objects.
  40.  * <p>
  41.  * For the keyboard keys used by this component in the standard Look and
  42.  * Feel (L&F) renditions, see the
  43.  * <a href="doc-files/Key-Index.html#JSpinner">JSpinner</a> key assignments.
  44.  * <b>Note:</b> The link above is only a placeholder. It will not be valid
  45.  *              until this component is released.
  46.  *
  47.  * @author James Gosling
  48.  */
  49. public class Spinner extends JComponent implements Adjustable, AdjustmentListener, 
  50.                                                    FocusListener, KeyListener, MouseListener
  51. {
  52.   protected String txt;
  53.   protected Dimension d;
  54.   protected int ascent;
  55.   protected int value;
  56.   protected boolean haveFocus = false;
  57.   protected int minValue = 0;
  58.   protected int maxValue = 0x7FFFFF;
  59.   protected FontMetrics fm;
  60.   protected int nDigits = 4;
  61.   protected int digitsTyped = 0;
  62.   protected boolean wraps = false;
  63.   protected boolean borderPainted = false;
  64.   protected Color backgroundColor = Color.white;
  65.   protected int leadingPad = -1;
  66.   
  67.   public boolean wrapped= false;
  68.  
  69.   public Spinner(int startValue, String t) {
  70. //     txt = t;
  71. //     value = init;
  72. //     enableEvents(AWTEvent.FOCUS_EVENT_MASK
  73. //               |AWTEvent.KEY_EVENT_MASK|AWTEvent.MOUSE_EVENT_MASK);
  74. //     updateUI();
  75.     init(startValue,t);
  76.   }
  77.   public Spinner(int startValue) {
  78. //     value = init;
  79. //     enableEvents(AWTEvent.FOCUS_EVENT_MASK
  80. //               |AWTEvent.KEY_EVENT_MASK|AWTEvent.MOUSE_EVENT_MASK);
  81. //     updateUI();
  82.     init(startValue,null);
  83.   }
  84.  
  85.   private void init(int startValue, String t)
  86.   {
  87.     txt = t;
  88.     value = startValue;
  89.     addFocusListener(this);
  90.     addMouseListener(this);
  91.     addKeyListener(this);
  92.     updateUI();
  93.   }
  94.   
  95.   
  96.   /**
  97.    * Gets the current value of the Spinner object.
  98.    */
  99.   public int getValue() { return value; }
  100.   
  101.   /**
  102.    * Sets the current value of the Spinner. This
  103.    * value must be within the range defined by the minimum and
  104.    * maximum values for this object.
  105.    * @param v the current value
  106.    */
  107.   public void setValue(int v) {
  108.     if(wraps)
  109.       {
  110.         if((v<minValue) || (v>maxValue)) wrapped = true;
  111.         else wrapped = false;
  112.       }
  113.     while (v < minValue)
  114.       if(wraps) v = maxValue+1-minValue+v;
  115.       else v = minValue;
  116.     while (v > maxValue)
  117.       if(wraps) v = minValue-1+v-maxValue;
  118.       else v = maxValue;
  119.     if (value!=v){
  120.       value = v;
  121.       if (isShowing()) repaint(20);
  122.       fireAdjustmentValueChanged(new AdjustmentEvent
  123.                                       (this, 0, AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, v));
  124.     }
  125.   }
  126.   /** A Spinner for which wrapping is true wraps around to the minimum
  127.     value when the maximum value is exceeded, and vice versa.
  128.     @param w true if wrapping is to be enabled, false if the
  129.     value is to be clamped. */
  130.   public void setWrap(boolean w) { wraps = w; }
  131.   public boolean getWrap() { return wraps; }
  132.   /** A Spinner can have a string associated with it, which is placed
  133.     at the right of the number
  134.     @param s the new text value */
  135.   public void setText(String s) { txt = s; if(isShowing()) repaint(20); }
  136.   public String getText() { return txt; }
  137.   public void setFont(Font f) {
  138.     if (f != getFont()) {
  139.       super.setFont(f);
  140.       d = null;
  141.       invalidate();
  142.     }
  143.   }
  144.   public void setDigits(int n) { nDigits = n; }
  145.   public int getDigits() { return nDigits; }
  146.   public void setLeadingPad(int newPad) {leadingPad = newPad;}
  147.   public int getLeadingPad() {return leadingPad;}
  148.   public void setBackgroundColor(Color newColor) {backgroundColor = newColor;}
  149.   public Color getBackgroundColor() {return backgroundColor;}
  150.   
  151. //   protected void processFocusEvent(FocusEvent e){
  152. //     if ((e.getID()==e.FOCUS_GAINED)!=haveFocus) {
  153. //       haveFocus = !haveFocus;
  154. //       if(haveFocus)
  155. //      {
  156. //        digitsTyped = 0;
  157. //      }
  158. //       repaint();
  159. //     }
  160. //   }
  161. //   protected void  processKeyEvent(KeyEvent e){
  162. //     if (e.getID() != e.KEY_PRESSED) return;
  163. //     if (e.isActionKey())
  164. //       switch(e.getKeyCode()) {
  165. //       case e.VK_DOWN:    setValue(value-1); break;
  166. //       case e.VK_UP:      setValue(value+1); break;
  167. //       }
  168. //     else {
  169. //       int c = e.getKeyChar();
  170. //       if ('0'<=c && c<='9') {
  171.         
  172. //      if(digitsTyped < nDigits)
  173. //        {
  174. //          if (digitsTyped == 0)
  175. //            {
  176. //              value = 0;
  177. //            }
  178. //          int nv = value*10+c-'0';
  179. //          if ((nv<=maxValue) && (nv>=minValue))
  180. //            {
  181. //              // int M = 10;
  182. //              //            int Mn = 0;
  183. //              //            while ((Mn=M*10)<nv && Mn>M) M = Mn;
  184. //              //            nv = nv%M;
  185. //              setValue(nv);
  186. //              digitsTyped++;
  187. //            }
  188. //        }
  189. //       }
  190. //       else switch(c) {
  191. //       case 0177:
  192. //       case '\b': 
  193. //      if((value/10) >= 1)
  194. //        {
  195. //          setValue(value/10);
  196. //          digitsTyped--;
  197. //        }
  198. //      break;
  199. //       case '-': setValue(-value); break;
  200. //      //case '\t': transferFocus(); break;
  201. //       }
  202. //     }
  203. //     return;
  204. //   }
  205. //   protected void processMouseEvent(MouseEvent e){
  206. //     if (e.getID()==e.MOUSE_PRESSED) requestFocus();
  207. //     return;
  208. //   }
  209.   
  210.  
  211.   public boolean isFocusTraversable() { return true; }
  212.  
  213.   public boolean hasFocus() {return haveFocus;}
  214.  
  215.   public boolean isBorderPainted() {return borderPainted;}
  216.  
  217.   public void setBorderPainted(boolean b) 
  218.   {
  219.         borderPainted = b;
  220.         invalidate();
  221.   }
  222.  
  223.     /**
  224.      * Paint the spinner's border if BorderPainted property is true.
  225.      * 
  226.      * @see #paint
  227.      * @see #setBorder
  228.      */
  229.     protected void paintBorder(Graphics g) {    
  230.         if (isBorderPainted()) {
  231.             super.paintBorder(g);
  232.         }
  233.     }
  234.  
  235.   /** Spinners can both send and recieve AdjustmentEvents -- they
  236.    * can be cascaded together for situations where there are multiple
  237.    * ways to enter the same value (popup menu or typin number) */
  238.   public void adjustmentValueChanged(AdjustmentEvent e) {
  239.     setValue(e.getValue());
  240.   }
  241.   
  242.   /**
  243.    * Sets the minimum value of the Spinner.
  244.    * @param min the minimum value
  245.    */
  246.   public void setMinimum(int min){minValue=min;setValue(value);}
  247.   
  248.   /**
  249.    * Gets the minimum value of the Spinner.
  250.    */
  251.   public int getMinimum(){return minValue;}
  252.   
  253.   /**
  254.    * Sets the maximum value of the Spinner.
  255.    * @param max the maximum value
  256.    */
  257.   public void setMaximum(int max){maxValue=max;setValue(value);}
  258.   
  259.   /**
  260.    * Gets the maximum value of the Spinner.
  261.    */
  262.   public int getMaximum(){return maxValue;}
  263.   
  264.   /**
  265.    * Add a listener to recieve adjustment events when the value of
  266.    * the Spinner changes.
  267.    * @param l the listener to recieve events
  268.    * @see AdjustmentEvent
  269.    */
  270.   public void addAdjustmentListener(AdjustmentListener l){
  271.       listenerList.add(AdjustmentListener.class, l);
  272.   }
  273.   
  274.   /**
  275.    * Removes an adjustment listener.
  276.    * @param l the listener being removed
  277.    * @see AdjustmentEvent
  278.    */
  279.   public void removeAdjustmentListener(AdjustmentListener l){
  280.       listenerList.remove(AdjustmentListener.class, l);
  281.   }
  282.   
  283.     /*
  284.      * Notify all listeners that have registered interest for
  285.      * notification on this event type.  The event instance 
  286.      * is lazily created using the parameters passed into 
  287.      * the fire method.
  288.      * @see EventListenerList
  289.      */
  290.     protected void fireAdjustmentValueChanged(AdjustmentEvent e) {
  291.         // Guaranteed to return a non-null array
  292.         Object[] listeners = listenerList.getListenerList();
  293.         // Process the listeners last to first, notifying
  294.         // those that are interested in this event
  295.         for (int i = listeners.length-2; i>=0; i-=2) {
  296.             if (listeners[i]==AdjustmentListener.class) {
  297.                 // Lazily create the event:
  298.                 // if (e == null)
  299.                 // e = new WindowEvent(this.popup, event.getID());
  300.                 ((AdjustmentListener)listeners[i+1]).adjustmentValueChanged(e);
  301.             }          
  302.         }
  303.     }   
  304.  
  305.   /**
  306.    * Does nothing -- part of the Adjustable interface.
  307.    * @param u the unit increment
  308.    */
  309.   public void setUnitIncrement(int u){};
  310.   
  311.   /**
  312.    * Does nothing -- part of the Adjustable interface.
  313.    */
  314.   public int getUnitIncrement(){return 1;};
  315.   
  316.   /**
  317.    * Does nothing -- part of the Adjustable interface.
  318.    * @param b the block increment
  319.    */
  320.   public void setBlockIncrement(int b){};
  321.   
  322.   /**
  323.    * Does nothing -- part of the Adjustable interface.
  324.    */
  325.   public int getBlockIncrement(){return 1;}
  326.   
  327.   /**
  328.    * Does nothing -- part of the Adjustable interface.
  329.    * @param v the length of the indicator
  330.    */
  331.   public void setVisibleAmount(int v){};
  332.   
  333.   /**
  334.    * Does nothing -- part of the Adjustable interface.
  335.    */
  336.   public int getVisibleAmount(){return 1;}
  337.   
  338.   /**
  339.    * Does nothing -- part of the Adjustable interface.
  340.    */
  341.   public int getOrientation(){return HORIZONTAL;};
  342.  
  343.   public void keyTyped(KeyEvent e) {}
  344.   public void keyPressed(KeyEvent e)
  345.   {
  346.     if (e.isActionKey())
  347.       switch(e.getKeyCode()) {
  348.       case e.VK_DOWN:    setValue(value-1); break;
  349.       case e.VK_UP:      setValue(value+1); break;
  350.       }
  351.     else {
  352.       int c = e.getKeyChar();
  353.       if ('0'<=c && c<='9') {
  354.         
  355.         if(digitsTyped < nDigits)
  356.           {
  357.             if (digitsTyped == 0)
  358.               {
  359.                 value = 0;
  360.               }
  361.             int nv = value*10+c-'0';
  362.             if ((nv<=maxValue) && (nv>=minValue))
  363.               {
  364.                 // int M = 10;
  365.                 //            int Mn = 0;
  366.                 //            while ((Mn=M*10)<nv && Mn>M) M = Mn;
  367.                 //            nv = nv%M;
  368.                 setValue(nv);
  369.                 digitsTyped++;
  370.               }
  371.           }
  372.       }
  373.       else switch(c) {
  374.       case 0177:
  375.       case '\b': 
  376.         setValue(value/10);
  377.         digitsTyped--;
  378.         break;
  379.       case '-': setValue(-value); break;
  380.         //case '\t': transferFocus(); break;
  381.       }
  382.     }
  383.     return;
  384.   }
  385.   public void keyReleased(KeyEvent e){}
  386.   public void mouseClicked(MouseEvent e) {}
  387.   public void mousePressed(MouseEvent e) 
  388.   {
  389.     requestFocus();
  390.     return;
  391.   }
  392.   public void mouseReleased(MouseEvent e) {}
  393.   public void mouseEntered(MouseEvent e) {}
  394.   public void mouseExited(MouseEvent e) {}
  395.   public void focusGained(FocusEvent e) 
  396.   {
  397.     haveFocus = true;
  398.     digitsTyped = 0;
  399.     repaint();
  400.   }
  401.   public void focusLost(FocusEvent e)
  402.   {
  403.     haveFocus = false;
  404.     repaint();
  405.   }
  406.  
  407.  
  408.  
  409.     
  410.   public SpinnerUI getUI() {
  411.     return (SpinnerUI)ui;
  412.   }
  413.      
  414.   public void setUI(SpinnerUI ui) {
  415.     super.setUI(ui);
  416.   }
  417.  
  418.   public void updateUI() 
  419.   {
  420.     setUI((SpinnerUI)UIManager.getUI(this));
  421.   }
  422.  
  423.     /**
  424.      * @return "SpinnerUI"
  425.      * @see JComponent#getUIClassID
  426.      * @see UIDefaults#getUI
  427.      */
  428.     public String getUIClassID() {
  429.         return "SpinnerUI";
  430.     }
  431. }
  432.